home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / iutil / accbuf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-24  |  5.5 KB  |  286 lines

  1. # include    <ingres.h>
  2. # include    <access.h>
  3. # include    <aux.h>
  4. # include    <lock.h>
  5. # include    <opsys.h>
  6.  
  7. /*
  8. **    access method buffers and other data areas for buffer maintenance
  9. */
  10.  
  11. struct accbuf    Acc_buf[NACCBUFS];    /* the buffers */
  12. struct accbuf    *Acc_head;        /* head of usage list */
  13. struct accbuf    *Acc_tail;        /* tail of usage list */
  14. struct lockreq    Lock;
  15.  
  16. /*
  17. **    structs for admin file data
  18. */
  19.  
  20. struct admin    Admin;
  21.  
  22. /*
  23. **    global flag indicating if access methods
  24. **    have been initialized.
  25. */
  26.  
  27. int        Acc_init    =    FALSE;
  28.  
  29. char        Acclock;        /* locks enabled flag */
  30. extern int        Alockdes;        /* file descriptor for lock device*/
  31. int        Lockrel;        /* lock relations flag*/
  32.  
  33. /*
  34. **    Flush the indicated page and reset all
  35. **    important information including the name
  36. **
  37. **    Trace Flags:
  38. **        20.0,1
  39. */
  40.  
  41. int
  42. resetacc(buf)
  43. struct accbuf    *buf;
  44. {
  45.     register struct accbuf    *b;
  46.     register int        i;
  47.  
  48.     b = buf;
  49.     if (b == 0)
  50.         b = Acc_head;
  51. #    ifdef xATR3
  52.     if (tTf(20, 0))
  53.     {
  54.         printf("RESETACC: %x=", b);
  55.         dumptid((TID *) &b->rel_tupid);
  56.     }
  57. #    endif
  58.  
  59.     i = pageflush(b);    /* write the page if necessary */
  60.     b->rel_tupid = -1;
  61.     b->filedesc = -1;
  62.     b->thispage = -1;
  63.     b->bufstatus = 0;
  64.     return (i);
  65. }
  66.  
  67. /*
  68. **    initialize access method data areas
  69. **
  70. **    Trace Flags:
  71. **        20.2,3
  72. */
  73.  
  74. void
  75. acc_init()
  76. {
  77.     register struct accbuf    *last;
  78.     register struct accbuf    *b;
  79.     struct stat        stbuf;
  80.     extern int        errno;
  81.  
  82. #    ifdef xATR3
  83.     if (tTf(20, 2))
  84.         printf("ACC_INIT=%d\n", Acc_init);
  85. #    endif
  86.  
  87.     if (Acc_init)
  88.         return;        /* already initialized */
  89.     last = 0;
  90.     for (b = Acc_buf; b < &Acc_buf[NACCBUFS]; )
  91.     {
  92.         resetacc(b);
  93.         b->modb = last;
  94.         last = b;
  95.         b++;
  96.         last->modf = b;
  97.     }
  98.     last->modf = 0;
  99.     Acc_head = Acc_buf;
  100.     Acc_tail = last;
  101.  
  102.     /* get the admin file */
  103.     readadmin();
  104.  
  105.     /*
  106.     ** Set up locking information. If the database has concurrency
  107.     ** control then Lockrel = TRUE and the concurrency device will
  108.     ** be opened for writing. If there is no concurrency for the
  109.     ** data base or if the lock device isn't installed, then Alockdes
  110.     ** = -1 and no locking will (or can) occure.
  111.     */
  112.     Lockrel = (Admin.adhdr.adflags & A_DBCONCUR) != 0;
  113.     if (Lockrel && Alockdes < 0)
  114.         Alockdes = start_up_lock_driver();
  115.     errno = 0;    /* clear in case /dev/lock isn't available */
  116.     Acclock = TRUE;
  117.     stat(".", &stbuf);
  118.     bmove((char *) &stbuf, (char *) Lock.dbnode, 4);
  119.  
  120.     Acc_init = TRUE;
  121. }
  122.  
  123. /*
  124. **    place buffer at top of LRU list
  125. */
  126.  
  127. int
  128. top_acc(buf)
  129. struct accbuf    *buf;
  130. {
  131.     register struct accbuf    *b;
  132.  
  133.     b = buf;
  134.  
  135.     if (b == Acc_head)
  136.         return (0);
  137.     if (b == Acc_tail)
  138.         Acc_tail = b->modb;
  139.     else
  140.         b->modf->modb = b->modb;
  141.     b->modb->modf = b->modf;
  142.     Acc_head->modb = b;
  143.     b->modf = Acc_head;
  144.     Acc_head = b;
  145.     b->modb = 0;
  146.     return (0);
  147. }
  148.  
  149. /*
  150. ** Flush_rel -- flush all pages associated with the relation
  151. **    described by the descriptor. If resetflag is TRUE,
  152. **    then the buffers are reset so the pages will not be
  153. **    found on subsequent calls to find_page().
  154. **
  155. **    Returns "or'ed" result from calls to pageflush.
  156. **
  157. **    Trace Flags:
  158. **        20.4-5
  159. */
  160.  
  161. int
  162. flush_rel(d, resetflag)
  163. register DESC    *d;
  164. int        resetflag;
  165. {
  166.     register struct accbuf    *b;
  167.     register int        i;
  168.  
  169. #    ifdef xATR3
  170.     if (tTf(20, 4))
  171.         printf("flush_rel: rel=%.14s, reset=%d\n", d->reldum.relid, resetflag);
  172. #    endif
  173.  
  174.     i = 0;
  175.     for (b = Acc_head; b != NULL; b = b->modf)
  176.     {
  177.         if (d->reltid.ltid == b->rel_tupid)
  178.         {
  179.             if (resetflag)
  180.                 i |= resetacc(b);
  181.             else
  182.                 i |= pageflush(b);
  183.         }
  184.     }
  185.  
  186.     return (i);
  187. }
  188.  
  189. /*
  190. **    CHOOSE_BUF -- Try to find an empty buffer for assignment.
  191. **        If there is no empty buffer, pick the last buffer
  192. **        in the LRU queue and make sure it is flushed.
  193. **
  194. **        Choose_buf guarantees that the buffer will be reset
  195. **        if it was used previously for a different relation.
  196. **
  197. **    Choose_buf -- choose a buffer for use with the given relation on
  198. **    the given page. The current algorithm is to allow only one buffer
  199. **    per relation. If a relation does not have a buffer, it is given a
  200. **    free one (if any) or else the Least Recently Used.
  201. **
  202. **    Trace Flags:
  203. **        29.0,1
  204. */
  205.  
  206. struct accbuf *
  207. choose_buf(dx, pageid)
  208. DESC    *dx;
  209. long    pageid;
  210. {
  211.     register struct accbuf    *b, *free;
  212.     register DESC        *d;
  213.     struct accbuf        *mine;
  214.  
  215.     d = dx;
  216.     free = mine = NULL;
  217.  
  218.     for (b = Acc_head; b != 0; b = b->modf)
  219.     {
  220.         if (b->rel_tupid == -1)
  221.             free = b;
  222.         else
  223.             if (d->reltid.ltid == b->rel_tupid)
  224.             {
  225.                 if (pageid == b->thispage)
  226.                 {
  227.                     if (d->relopn < 0)
  228.                         b->filedesc = d->relfp;
  229.                     return (b);
  230.                 }
  231.                 mine = b;
  232.             }
  233.     }
  234.  
  235.     /*
  236.     ** "Free" and "Mine" now reflect the current state of the buffers.
  237.     ** There is no buffer with the currently requested page
  238.     */
  239.  
  240. #    ifdef xATR3
  241.     if (tTf(29, 1))
  242.         printf("choosebuf free %x,mine %x\n", free, mine);
  243. #    endif
  244.  
  245.     /* no current buffer. Choose a free one or LRU */
  246.     if (free == NULL)
  247.         free = resetacc(Acc_tail) ? NULL : Acc_tail;    /* error if can't reset the LRU */
  248.     if (free)
  249.     {
  250.         /* copy relevant material (in this order in case of rubout) */
  251.         free->filedesc = d->relfp;
  252.         free->rel_tupid = d->reltid.ltid;
  253.     }
  254.  
  255. #    ifdef xATR1
  256.     if (tTf(29, 0))
  257.         printf("choosebuf:rets %x\n", free);
  258. #    endif
  259.     return (free);
  260. }
  261.  
  262. /*
  263. **    ACC_CLOSE -- flush any buffers left around
  264. **        and then close the files for relation & attribute.
  265. **        The relation and attribute relation are normally left open
  266. **        until the end of an INGRES session but must be closed
  267. **        and re-opened in the dbu's whenever a new overlay is loaded.
  268. */
  269.  
  270. int
  271. acc_close()
  272. {
  273.     register int    i;
  274.  
  275.     if (i = pageflush((struct accbuf *) NULL))
  276.         syserr("acc_close: pageflush %d", i);
  277.     close(Admin.adreld.relfp);
  278.     close(Admin.adattd.relfp);
  279.     Admin.adreld.relopn = Admin.adattd.relopn = 0;
  280.     if (Alockdes >= 0)
  281.         close(Alockdes);
  282.     Alockdes = -1;
  283.     Acc_init = FALSE;
  284.     return (0);
  285. }
  286.